﻿using SimpleInjector;
using Sustainalytics.Claims;
using Sustainalytics.DataLayer;
using Sustainalytics.DataLayer.PI;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities;
using Sustainalytics.MongoDB.Extensions;
using System.Collections.Generic;
using System.Configuration.Abstractions;
using System.Web.Http;
using Sustainalytics.News.BusinessLogic;
using Sustainalytics.Replication.Publisher;

namespace Sustainalytics.News.Service
{
    public static class CompositionRoot
    {
        private static readonly Dictionary<string, string> serviceBusParams = new Dictionary<string, string>
                {
                        { "ConnectionString", ConfigurationManager.Instance.AppSettings["Microsoft.ServiceBus.ConnectionString"] },
                        { "RegionEndpoint", ConfigurationManager.Instance.AppSettings["Microsoft.ServiceBus.RegionEndpoint"] },
                        { "SessionId", ConfigurationManager.Instance.AppSettings["Microsoft.ServiceBus.SessionId"] },
                        { "TopicPath", ConfigurationManager.Instance.AppSettings["Microsoft.ServiceBus.TopicPath"] },
                };
        
        public static Container RegisterDependencies(HttpConfiguration config)
        {
            var container = new Container();

            container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
            container.RegisterWebApiControllers(config);

            var clientPlatformConnectionString = ConfigurationManager.Instance.ConnectionStrings["ClientPlatform"].ConnectionString;

            container.RegisterMisc(serviceBusParams);

            container.RegisterCollections(
                clientPlatformConnectionString);

            container.RegisterRepositories(clientPlatformConnectionString);

            container.RegisterBussinessLogic(clientPlatformConnectionString);

            container.Verify();
            return container;
        }

        private static void RegisterCollections(this Container container,
           string clientPlatformConnectionString)
        {
            container.Register(typeof(IRepositoryCollection<UserFilterSettings>), () => new RepositoryCollection<UserFilterSettings>(clientPlatformConnectionString));
            container.Register(typeof(IRepositoryCollection<NewsArticle>), () => new RepositoryCollection<NewsArticle>(clientPlatformConnectionString));
        }

        private static void RegisterRepositories(this Container container,
           string clientPlatformConnectionString)
        {
            container.Register(typeof(INewsRepository), () => NewsRepository.GetNewsRepository(clientPlatformConnectionString));
            container.Register(typeof(INotificationsRepository), () => NotificationsRepository.GetNotificationRepository(clientPlatformConnectionString));
            container.Register(typeof(IAccountsRepository), () => AccountsRepository.GetAccountsRepository(clientPlatformConnectionString));
        }

        private static void RegisterBussinessLogic(this Container container,
            string clientPlatformConnectionString)
        {
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ResultOutput>(clientPlatformConnectionString));
        }

        private static void RegisterMisc(
            this Container container,
            Dictionary<string, string> serviceBusParams
            )
        {
            container.Register(() => MongoFactory.GetConnectionStrings());
            container.RegisterSingleton(typeof(IClaimsChecker), () => new ClaimsChecker());
            container.RegisterSingleton(typeof(INewsManagement), () => new NewsManagement(container.GetInstance<INewsRepository>(),container.GetInstance<IAccountsRepository>(), container.GetInstance<ServiceBusPublisher>()));
            container.RegisterSingleton(typeof(INotificationsManagement), () => new NotificationsManagement(container.GetInstance<INotificationsRepository>(), container.GetInstance<ServiceBusPublisher>()));
            container.RegisterSingleton(() => { return new ServiceBusPublisher(serviceBusParams); });
        }
    }
}